package org.eclipse.emf.index.omds.core.indexer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.index.IndexStore;
import org.eclipse.emf.index.internal.LogFacade;
import org.eclipse.emf.index.resource.IndexFeeder;
import org.eclipse.emf.index.resource.ResourceIndexer;
import org.eclipse.jst.j2ee.ejb.Entity;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.javaee.ejb.EnterpriseBeans;
import org.eclipse.jst.javaee.ejb.SessionBean;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;


public class OMSResourceIndexer implements ResourceIndexer {

	public void resourceChanged(URI resourceURI, IndexFeeder indexFeeder) {
		// translate the resource URI to a workbench file
		IFile file = WorkbenchResourceHelper.getPlatformFile(resourceURI);
		System.out.println("The following resource is changed :: "+resourceURI.toString());
		
		// get file's project
		IProject project = file.getProject();
		
		// get the model provider of the project
		IModelProvider modelProvider = ModelProviderManager.getModelProvider(project);
		if (modelProvider == null) {
			// there is no EMF model behind the changed resource
			return;
		}
		
		Object modelObject = modelProvider.getModelObject();
		System.out.println("The name of the model :: "+modelObject.toString());
		
		if (modelObject == null) {
			// there is no EMF model behind the changed resource
			System.out.println("There is no EMF model behind the changed resource.");
			return;
		}
		
		
		// Web 2.5 projects
		if(modelObject instanceof org.eclipse.jst.javaee.web.WebApp){					
			//Defines the WebApp
			System.out.println("Web 2.5 project resource is changed...");
			org.eclipse.jst.javaee.web.WebApp webApp = (org.eclipse.jst.javaee.web.WebApp)modelObject;	
			HashMap packageMap = new HashMap();
			
			//Adding Servelets to the index.
			List<org.eclipse.jst.javaee.web.Servlet> servlets = webApp.getServlets();
			for (org.eclipse.jst.javaee.web.Servlet servlet : servlets) {
				System.out.println("Indexing servelet : " + servlet.getServletName());
				packageMap.put(servlet.getServletName(),servlet.getServletClass()+"+"+project.getName());
				 indexFeeder.createEObjectDescriptor(
					      (EObject) servlet, 
					      servlet.getServletName(), 
					      getFirstDisplayName(servlet.getDisplayNames(), servlet.getServletClass()), 
					      packageMap);				 
			}
			
			//Adding Filters to the index.
			List<org.eclipse.jst.javaee.web.Filter> filters = webApp.getFilters();
			for (org.eclipse.jst.javaee.web.Filter filter : filters) {
				System.out.println("Indexing Filter : " + filter.getFilterName());
				packageMap.put(filter.getFilterName(),filter.getFilterClass()+"+"+project.getName());
				 indexFeeder.createEObjectDescriptor(
					      (EObject) filter, 
					      filter.getFilterClass(), 
					      getFirstDisplayName(filter.getDisplayNames(), filter.getFilterClass()), 
					      packageMap);
			}
			
			//Adding Listeners to the index.
			List<org.eclipse.jst.javaee.core.Listener> listeners = webApp.getListeners();
			for (org.eclipse.jst.javaee.core.Listener listener : listeners) {
				System.out.println("Indexing Listener : " + listener.getListenerClass());
				String tempDisplayName = listener.getListenerClass();
				int m = tempDisplayName.lastIndexOf('.');
				String listenerName = tempDisplayName.substring(m+1);
				packageMap.put(listenerName,listener.getListenerClass()+"+"+project.getName());
				indexFeeder.createEObjectDescriptor(
					      (EObject) listener, 
					      listener.getListenerClass(), 
					      getFirstDisplayName(listener.getDisplayNames(), listener.getListenerClass()), 
					      packageMap);
			}
		} 
		
		else if (modelObject instanceof org.eclipse.jst.j2ee.webapplication.WebApp) {
			// this is the model of a Web 2.2-2.4 project
			System.out.println("Web 2.2-2.4 project resource is changed...");
			org.eclipse.jst.j2ee.webapplication.WebApp webApp = (org.eclipse.jst.j2ee.webapplication.WebApp)modelObject;
			HashMap packageMap = new HashMap();
			
			List<org.eclipse.jst.j2ee.webapplication.Servlet> servlets = webApp.getServlets();
			for(org.eclipse.jst.j2ee.webapplication.Servlet servlet : servlets){
				System.out.println("Indexing Servelet : "+ servlet.getServletName());
				String packageName = servlet.getServletName();     //The package name if the Servelt Class should be added.
				packageMap.put(servlet.getServletName(), packageName+"+"+project.getName());
				indexFeeder.createEObjectDescriptor(
					      (EObject) servlet, 
					      servlet.getServletName(), 
					      getFirstDisplayName(servlet.getDisplayNames(), servlet.getServletName()), 
					      packageMap);
			}
			
			List<org.eclipse.jst.j2ee.webapplication.Filter> filters = webApp.getFilters();
			for(org.eclipse.jst.j2ee.webapplication.Filter filter : filters){
				System.out.println("Indexing Filters : "+ filter.getFilterClassName());
				packageMap.put(filter.getFilterClassName(),filter.getFilterClassName()+"+"+project.getName() );   //The package name should be added.
				indexFeeder.createEObjectDescriptor(
					      (EObject) filter, 
					      filter.getFilterClassName(), 
					      getFirstDisplayName(filter.getDisplayNames(), filter.getFilterClassName()), 
					      packageMap);
			}
			
			List<org.eclipse.jst.j2ee.common.Listener> listeners = webApp.getListeners();
			for(org.eclipse.jst.j2ee.common.Listener listener : listeners){
				System.out.println("Indexing Listeners : "+ listener.getListenerClassName());
				packageMap.put(listener.getListenerClassName(),listener.getListenerClassName()+"+"+project.getName());   //The package name should be added.
				indexFeeder.createEObjectDescriptor(
					      (EObject) listener, 
					      listener.getListenerClassName(), 
					      getFirstDisplayName(listener.getDisplayNames(), listener.getListenerClassName()), 
					      packageMap);
			}
		
		}
		
		else if (modelObject instanceof org.eclipse.jst.javaee.ejb.EJBJar) {
			// this is the model of a EJB 3.0 project
			
			System.out.println("EJB 3.0 project resource is changed...");
			org.eclipse.jst.javaee.ejb.EJBJar ejbJar = (org.eclipse.jst.javaee.ejb.EJBJar)modelObject;
			HashMap packageMap = new HashMap();
			
			List<org.eclipse.jst.javaee.ejb.SessionBean>sessionBeans = (List<SessionBean>)ejbJar.getEnterpriseBeans().getSessionBeans();
			for(org.eclipse.jst.javaee.ejb.SessionBean bean : sessionBeans){
				System.out.println("Indexing SessionBean : "+ bean.getEjbName());
				packageMap.put(bean.getEjbName(),bean.getEjbClass()+"+"+project.getName());  
				indexFeeder.createEObjectDescriptor(
					      (EObject) bean, 
					      bean.getEjbName(), 
					      getFirstDisplayName(bean.getDisplayNames(), bean.getEjbName()), 
					      packageMap);
			}
			
			//Adding Message Driven Beans
			List<org.eclipse.jst.javaee.ejb.MessageDrivenBean>msgDrivenBeans = ejbJar.getEnterpriseBeans().getMessageDrivenBeans();
			for(org.eclipse.jst.javaee.ejb.MessageDrivenBean msgDrivenBean : msgDrivenBeans){
				System.out.println("indexing MessageDrivenBean : "+ msgDrivenBean.getEjbName());
				packageMap.put(msgDrivenBean.getEjbName(),msgDrivenBean.getEjbClass()+"+"+project.getName() );
				indexFeeder.createEObjectDescriptor(
					      (EObject) msgDrivenBean, 
					      msgDrivenBean.getEjbName(), 
					      getFirstDisplayName(msgDrivenBean.getDisplayNames(), msgDrivenBean.getEjbName()), 
					      packageMap);
			}
		} 
		
		else if (modelObject instanceof org.eclipse.jst.j2ee.ejb.EJBJar) {
			// this is the model of a EJB 1.1-2.1 project
			
			System.out.println("EJB 1.1 - 2.1 project resource is changed...");
			org.eclipse.jst.j2ee.ejb.EJBJar ejbJar = (org.eclipse.jst.j2ee.ejb.EJBJar)modelObject;
			HashMap packageMap = new HashMap();
			
			List<org.eclipse.jst.j2ee.ejb.Session> beans = ejbJar.getSessionBeans();
			for(org.eclipse.jst.j2ee.ejb.Session bean : beans){
				System.out.println("indexing SessionBean : "+ bean.getName());
				packageMap.put(bean.getEjbClassName(), bean.getEjbClassName()+"+"+project.getName());
				indexFeeder.createEObjectDescriptor(
					      (EObject) bean, 
					      bean.getEjbClassName(), 
					      getFirstDisplayName(bean.getDisplayNames(), bean.getName()), 
					      null);
			}
			
			List<org.eclipse.jst.j2ee.ejb.MessageDriven> messageDrivenBeans = ejbJar.getMessageDrivenBeans();
			for(org.eclipse.jst.j2ee.ejb.MessageDriven msgDrivenbean : messageDrivenBeans){
				System.out.println("indexing MessageDrivenBean : "+ msgDrivenbean.getName());
				packageMap.put(msgDrivenbean.getEjbClassName(),msgDrivenbean.getEjbClassName()+"+"+project.getName() );
				indexFeeder.createEObjectDescriptor(
					      (EObject) msgDrivenbean, 
					      msgDrivenbean.getEjbClassName(), 
					      getFirstDisplayName(msgDrivenbean.getDisplayNames(), msgDrivenbean.getName()), 
					      null);
			}
		}
	}
	
	private String getFirstDisplayName(List displayNames, String defaultValue) {
		  if (displayNames.size() > 0) { 
		   Object obj = displayNames.get(0);
		   if (obj instanceof org.eclipse.jst.javaee.core.DisplayName) {
		    return ((org.eclipse.jst.javaee.core.DisplayName) obj).getValue();
		   } else if (obj instanceof org.eclipse.jst.j2ee.common.DisplayName) {
		    return ((org.eclipse.jst.j2ee.common.DisplayName) obj).getValue();
		   }
		  }
		  return defaultValue;
		 }

	@Override
	public void resourceDeleted(URI resourceURI, IndexFeeder feeder) {
		try {
			feeder.deleteResourceDescriptor(resourceURI);
		} catch (Exception exc) {
			LogFacade.logError("Error deleting resource from index " + resourceURI, exc);
		}
	}

}
